<template>
  <ViewVideo
    v-if="videoData && !videoData.isDeleted && dataModels"
    :status="status"
    :related="relatedVideos?.items"
    :data="videoData"
    :total="relatedVideos?.allPages"
    :status-video="statusVideo"
    :suggested-videos="relatedVideos"
    :models="dataModels.items"
    :recent="relatedSearch && typeof relatedSearch === 'object' ? [] : relatedSearch"
    class="page-video"
  >
    <PlayerAsideVideos
      :aside-videos="relatedVideos"
      :status="status"
      class="video__aside"
    />
  </ViewVideo>
  <div
    v-else
    class="_loading"
  />
</template>

<script setup lang="ts">
import { SearchApiService } from '../../services/api/search.service';
import { VideosApiService } from '../../services/api/videos.service';
import { ModelsApiService } from '../../services/api/models.service';
import { AsyncData, ThumbSize } from '../../runtime';
import { CSS_BREAKPOINTS } from '../../config';

const featureFlags = useRuntimeConfig().public.featureFlags;

const pageName = useGetPureRouteName();

const [
  { data: videoData, status: statusVideo },
  { data: relatedVideos, status },
  { data: relatedSearch },
  { data: dataModels },
] = await Promise.all([
  useFetchVideo(featureFlags.FetchByUrlEnabled ? VideosApiService.getVideoByUrl : VideosApiService.getVideoById),
  useFetchRelatedVideos(featureFlags.FetchByUrlEnabled ? VideosApiService.getRelatedVideosByUrl : VideosApiService.getRelatedVideosById),
  useFetchRelatedSearch(SearchApiService.getPhrases),
  useFetchTopModels(ModelsApiService.getTop, 24, AsyncData.TopModelsMore, String(pageName)),
]);

const { t, locale } = useI18n();

const defaultLocale = useRuntimeConfig().public.locales.default;

// у видео нет перевода на текущий язык — canonical ведёт на дефолтную локаль
useSetSeoOverride(() => ({
  canonicalLocale: videoData.value && !videoData.value.isCanonical && locale.value !== defaultLocale
    ? defaultLocale
    : undefined,
}));

const title = computed(() => videoData.value?.title || '');
const description = computed(() => videoData.value?.description || '');
const pagePureName = useGetPureRouteName();
const { meta } = useMeta({
  t,
  pageKey: pagePureName,
  brandName: useAppConfig().brandName,
  sortOptions: [],
  text: title,
  secondText: description,
});

const webpThumbs = videoData.value?.thumbUrls?.webp;
const webpEntries = webpThumbs ? Object.entries(webpThumbs) : [];
if (webpEntries.length) {
  const imagesrcset = webpEntries
    .map(([size, url]) => `${url} ${size.split('x')[0]}w`)
    .join(', ');
  useHead({
    link: [{
      rel: 'preload',
      as: 'image',
      type: 'image/webp',
      imagesrcset,
      imagesizes: `(max-width: ${CSS_BREAKPOINTS.md}px) 100vw, 1248px`,
      fetchpriority: 'high',
    }],
  });
}

useHead(meta);

const ogImage = computed(() =>
  videoData.value?.thumbUrls?.webp?.[ThumbSize.Big]
  || videoData.value?.thumbUrls?.webp?.[ThumbSize.Medium]
  || videoData.value?.previewUrl
  || undefined
);

useHead(computed(() => ({
  meta: [
    { property: 'og:type', content: 'video.other' },
    { name: 'twitter:card', content: 'summary_large_image' },
    ...(ogImage.value ? [{ property: 'og:image', content: ogImage.value, key: 'og:image' }] : []),
  ],
})));

watchEffect(() => {
  if ((statusVideo.value === 'error' || statusVideo.value === 'success') && (!videoData.value || videoData.value.isDeleted)) {
    throw createError({ statusCode: 404, statusMessage: 'Problem loading video' });
  }
});

const { generateLink } = useGenerateLink();
const { siteUrl } = useAppConfig();

const embedUrl = videoData.value?.url
  ? `${siteUrl}${generateLink(`videos/${videoData.value.url}`)}`
  : undefined;

const videoJsonLd = computed(() => {
  const video = videoData.value;
  if (!video) return null;

  const createdISO = video.created ? new Date(video.created * 1000).toISOString() : undefined;

  const durationSeconds = video.duration || 0;
  const hours = Math.floor(durationSeconds / 3600);
  const minutes = Math.floor((durationSeconds % 3600) / 60);
  const seconds = durationSeconds % 60;
  const isoDuration = durationSeconds > 0
    ? `PT${hours ? hours + 'H' : ''}${minutes ? minutes + 'M' : ''}${seconds ? seconds + 'S' : ''}`
    : undefined;

  const actors = Array.isArray(video.models)
    ? video.models.filter(m => m?.title).map(m => ({ '@type': 'Person', name: m.title }))
    : [];
  const genres = Array.isArray(video.categories)
    ? video.categories.map(c => c?.title).filter(Boolean)
    : [];
  const keywords = Array.isArray(video.tags)
    ? video.tags.filter(Boolean)
    : [];

  return {
    '@context': 'https://schema.org',
    '@type': 'VideoObject',
    name: video.title || undefined,
    description: video.description || undefined,
    thumbnailUrl: [video.thumbUrls?.webp?.[ThumbSize.Big] || video.thumbUrls?.webp?.[ThumbSize.Medium] || video.previewUrl].filter(Boolean),
    uploadDate: createdISO,
    duration: isoDuration,
    contentUrl: video.videoUrl || undefined,
    embedUrl,
    interactionStatistic: video.views != null ? {
      '@type': 'InteractionCounter',
      interactionType: { '@type': 'https://schema.org/WatchAction' },
      userInteractionCount: video.views
    } : undefined,
    actor: actors.length ? actors : undefined,
    genre: genres.length ? genres : undefined,
    keywords: keywords.length ? keywords : undefined
  };
});

useHead(computed(() => videoJsonLd.value
  ? { script: [{ type: 'application/ld+json', innerHTML: JSON.stringify(videoJsonLd.value) }] }
  : {}
));
</script>

<style lang="scss">
.video__aside {
  @include from-br(md) {
    width: 288px;
  }
}
</style>
